angular.module('BaseControl')

.directive("refer", ['$compile','BaseConst', 'BaseEnum', 'BaseModule', 'BaseFunction',
    function($compile, BaseConst, BaseEnum, BaseModule, BaseFunction) {
    return {
        restrict: "E",  // 指令是一个元素 (并非属性)，备选项有"A"、"E" 和 "C"， "M" ,分别代表attribute、element、class和comment（默认值为"A"）
        scope: {
            value: '=?',
            change: '&',
            blur: '&',
            keydown: '&',
            beforeshow: '&'
        },
        templateUrl:        // 替换HTML (使用scope中的变量)
            'modules/Base/client/views/Refer.html',
        replace: true,          // 使用模板替换原始标记
        transclude: true,       // 不复制原始HTML内容
        controller: ['$scope', function($scope) {
            $scope.Module;
            $scope.DisplayText = '';
            $scope.Columns = new Array();
            $scope.ID = BaseFunction.getGuid();
            $scope.IsShowWindow = false;

            $scope.divClick = function(){
                event.stopPropagation();
            };

            $scope.textFocus = function(){
                if($scope.value != null && $scope.value != undefined){
                    $scope.DisplayText = $scope.value[$scope.CodeField];
                }
                else{
                     $scope.DisplayText = "";
                }
                $scope._InputElement.select();

                if(!$scope.IsFocuse){
                    $scope.IsFocuse = true;
                    document.addEventListener('click', $scope.BodyClick, true);
                }
            };
            $scope.textBlur = function(){
                if($scope.value != null && $scope.value != undefined){
                    $scope.DisplayText = $scope.value[$scope.TextField];
                }
                else{
                     $scope.DisplayText = "";
                }
            };

            $scope._IsTouchFind = false;    //是否触发了按编码模糊查找，如果触发了，将不执行blur事件
                                            //因为鼠标离开后，先执行textChange，如果查找时间长，那么会先执行blur，这样会有问题
            $scope.IsKeyDown = false;   //是否由KeyDown引发的TextChange
            $scope.textKeyDown = function(){
                $scope._IsTouchFind = false;
                if(event.keyCode == 13){
                    if(($scope.value == null || $scope.value == undefined) && $scope.DisplayText.trim() != "" ||
                        $scope.value != null && $scope.value != undefined && $scope.DisplayText.trim() != $scope.value[$scope.CodeField]){
                        if($scope.DisplayText.trim() != ""){
                            $scope.IsKeyDown = true;
                            $scope.textChange();
                            return;
                        }
                        else{
                           $scope.value = null;
                           $scope.$parent.$digest();
                           $scope.change({records: []});
                           $scope.keydown();
                        }
                    }
                    else{
                        $scope.keydown();
                    }
                }
                else{
                    $scope.keydown();
                }
            };

            $scope.textChange = function(){
                if(($scope.value == null || $scope.value == undefined) && $scope.DisplayText.trim() != "" ||
                    $scope.value != null && $scope.value != undefined && $scope.DisplayText.trim() != $scope.value[$scope.CodeField]){
                    if($scope.DisplayText.trim() != ''){
                        var condition = {};
                        //值克隆
                        for(key in $scope.Condition){ 
                            condition[key] = $scope.Condition[key];
                        }

                        condition[$scope.CodeField] = '/^' + $scope.DisplayText.trim() + '/';

                        $scope._IsTouchFind = true;
                        $scope.Module.find(condition, null, $scope.Module.Populate, 
                            function(records){
                                if(records.length == 1){
                                    $scope.value = records[0];
                                    $scope.$parent.$digest();
                                    $scope.change({records: records});
                                }
                                else if(records.length > 1){
                                    $scope.Module.Condition = condition;
                                    $scope.btnClick();
                                }                                
                                else{
                                    $scope.value = null;
                                    $scope.$parent.$digest();
                                    $scope.change({records: []});
                                }
                            }
                        );
                    }
                    else{
                        $scope.value = null;
                        $scope.$parent.$digest();
                        $scope.change({records: []});
                    }
                }
            }

            var isCreateDataGrid = false;
            var createDataGrid = function(){
                if (!isCreateDataGrid) {                    
                    var dataGridHtml = '<DataGrid module="Module" rowdblclick="rowDblClick()" isSelect="' + $scope.IsSelect.toString() + '" isedit="false" height="430px">';
                    for (var i = 0; i < $scope.Columns.length; i++) {
                        if($scope.Columns[i].Type == BaseEnum.ControlType.TextBox){
                            dataGridHtml += '<Column Type="TextBox" displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></Column>';
                        }
                        else if($scope.Columns[i].Type == BaseEnum.ControlType.CheckBox){
                            dataGridHtml += '<Column Type="CheckBox" displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></Column>';
                        }
                        else if($scope.Columns[i].Type == BaseEnum.ControlType.NumberBox){
                            if($scope.Columns[i].Round != null){
                                dataGridHtml += '<Column Type="NumberBox" displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" round="' + JSON.stringify($scope.Columns[i].Round) + '" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></Column>';
                            }
                            else{
                                dataGridHtml += '<Column Type="NumberBox" displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></Column>';
                            }
                        }
                        else if($scope.Columns[i].Type == BaseEnum.ControlType.PercentBox){
                            if($scope.Columns[i].Round != null){
                                dataGridHtml += '<Column Type="PercentBox" displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" round="' + JSON.stringify($scope.Columns[i].Round) + '" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></Column>';
                            }
                            else{
                                dataGridHtml += '<Column Type="PercentBox" displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></Column>';
                            }
                        }
                        else if($scope.Columns[i].Type == BaseEnum.ControlType.DropDownList){
                            var columnEnum = eval("$scope.$parent." + $scope.Columns[i].Enum);
                            if(columnEnum != undefined){
                                $scope.Columns[i].Enum = columnEnum;
                            }
                            else{
                                $scope.Columns[i].Enum = eval("$scope.$parent.$parent." + $scope.Columns[i].Enum);
                            }
                            dataGridHtml += '<Column Type="DropDownList" displayname="' + $scope.Columns[i].DisplayName + '" enum="Columns[' + i.toString() + '].Enum" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></Column>';
                        }
                        else if($scope.Columns[i].Type == BaseEnum.ControlType.Calendar){
                            if($scope.Columns[i].CalendarType == BaseEnum.DateTimeFormat.DateTime){
                                dataGridHtml += '<Column Type="Calendar" displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" calendartype="datetime" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></Column>';
                            }
                            else{
                                dataGridHtml += '<Column Type="Calendar" displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" calendartype="date" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></Column>';
                            }
                        }
                    }
                    dataGridHtml += '</DataGrid>';

                    $compile(dataGridHtml)($scope, function (clone, $scope) {
                        $scope._DataGridElement.appendChild(clone[0]);
                    });

                    if($scope.IsInclude){
                        $scope._ContentElement.style.display = "inline-table";
                        $scope._ContentElement.style.top = ((document.body.clientHeight - $scope._ContentElement.getBoundingClientRect().height) / 2 - $scope._ContentElement.getBoundingClientRect().top).toString() + 'px';
                    }
                    isCreateDataGrid = true;
                }
                else{
                    $scope.Module.emitReloadEvent();
                }
            }
            var show = function(isShow){
                if(isShow){
                    document.removeEventListener('click', $scope.BodyClick, true);
                    $('#' + $scope.ID).modal('show');
                }
                else{
                    $('#' + $scope.ID).modal('hide');
                    document.addEventListener('click', $scope.BodyClick, true);
                    $scope.IsShowWindow = false;
                    $scope._InputElement.focus();
                }
            }

            $scope.btnClick = function() {
                if(this.Enabled && !this.IsShowWindow){
                    if($scope.EntityName == undefined || $scope.EntityName == null || $scope.EntityName.trim() == ''){
                        event.stopPropagation();
                        return;
                    }
                    $scope.beforeshow({refScope: $scope});
                    show(true);
                    createDataGrid();
                }
            };
            $scope.btnRefOKClick = function(){
                if($scope.IsSelect){
                    var records = $scope.Module.getSelectRecords();

                    if(records.length > 0){
                        $scope.value = records[0];
                        $scope.$parent.$digest();
                        show(false);
                        $scope.change({records: records});
                    }
                    else{
                        BaseFunction.alert('请选择记录！');
                        event.stopPropagation();
                        return;
                    }
                }
                else{
                    if($scope.Module.FocusedRecord == null){
                        BaseFunction.alert('请选择记录！');
                        event.stopPropagation();
                        return;
                    }

                    if($scope.value == null || $scope.value == undefined || $scope.value[$scope.KeyField] != $scope.Module.FocusedRecord[$scope.KeyField]){
                        $scope.value = $scope.Module.FocusedRecord;
                        $scope.$parent.$digest();
                        $scope.change({records: [$scope.Module.FocusedRecord]});
                    }
                    show(false);
                }                
            };
            $scope.btnRefCancelClick = function(){
                show(false);
            };
            $scope.rowDblClick = function(){
                if($scope.value == null || $scope.value == undefined || $scope.value[$scope.KeyField] != $scope.Module.FocusedRecord[$scope.KeyField]){
                    $scope.value = $scope.Module.FocusedRecord;
                    $scope.$parent.$digest();
                    $scope.change({records: [$scope.Module.FocusedRecord]});
                }
                show(false);
            };

            $scope.$watch(
                function(){
                    return $scope.value;
                },
                function(){
                    if($scope.value != null && $scope.value != undefined){
                        if(document.activeElement == $scope._InputElement) {
                            $scope.DisplayText = $scope.value[$scope.CodeField];
                        }
                        else{
                            $scope.DisplayText = $scope.value[$scope.TextField];
                        }
                    }
                    else{
                        $scope.DisplayText = "";
                    }
                }
            );
        }],
        link: function (scope, element, attrs) {
            scope.Enabled = true;
            scope.Visible = true;
            scope.IsSelect = false;
            scope.IsInclude = false;    //是否包含在父容器里面
            scope.IsGrid = false;

            scope.EntityName;
            scope.Condition = null;
            scope.OrderBy = null;
            scope.Populate = "";
            scope.WindowTitle = '参照';
            scope.KeyField = '_id';
            scope.CodeField = 'Code';
            scope.TextField = 'Name';

            scope._InputElement = element[0].children[0].children[0];
            scope._ContentElement = element[0].children[1];
            scope._DataGridElement = element[0].children[1].children[0].children[0].children[1]; //angular.element(element[0].children[1].children[0].children[0].children[1]);

            if (attrs["entityname"] != undefined && attrs["entityname"].trim() != "") {
                scope.EntityName = attrs["entityname"].trim();
            }
            if (attrs["windowtitle"] != undefined && attrs["windowtitle"].trim() != "") {
                scope.WindowTitle = attrs["windowtitle"].trim();
            }
            if (attrs["keyfield"] != undefined && attrs["keyfield"].trim() != "") {
                scope.KeyField = attrs["keyfield"].trim();
            }
            if (attrs["codefield"] != undefined && attrs["codefield"].trim() != "") {
                scope.CodeField = attrs["codefield"].trim();
            }
            if (attrs["textfield"] != undefined && attrs["textfield"].trim() != "") {
                scope.TextField = attrs["textfield"].trim();
            }
            if (attrs["isselect"] != undefined && attrs["isselect"].toLocaleLowerCase() == "true") {
                scope.IsSelect = true;
            }
            if (attrs["isgrid"] != undefined && attrs["isgrid"].toLocaleLowerCase() == "true") {
                scope.IsGrid = true;
                element[0].children[0].children[0].setAttribute("class", "form-control ReferTextBox BaseControl GridBaseControl");
                element[0].children[0].children[1].children[0].setAttribute("class", "btn btn-default BaseControl GridBaseControl ReferBtn");
            }
            if (attrs["isinclude"] != undefined && attrs["isinclude"].toLocaleLowerCase() == "true") {
                scope.IsInclude = true;
            }
            if (attrs["condition"] != undefined && attrs["condition"].trim() != "") {
                scope.Condition = eval("(" + attrs["condition"].trim() + ")");
            }
            if (attrs["orderby"] != undefined && attrs["orderby"].trim() != "") {
                scope.OrderBy = eval("(" + attrs["orderby"].trim() + ")");
            }
            if (attrs["populate"] != undefined && attrs["populate"].trim() != "") {
                if(attrs["populate"].trim().substring(0, 1) == "{"){
                    scope.Populate = eval("(" + attrs["populate"].trim() + ")");
                }
                else{
                     scope.Populate = eval(attrs["populate"].trim());
                }
            }

            scope._InputElement.addEventListener('change', function(){ 
                if(!scope.IsKeyDown){
                    scope.$apply(scope.textChange());
                }
                else{
                    scope.IsKeyDown = false;
                }
            }, false);
            scope._InputElement.addEventListener('keydown', function(){ scope.$apply(scope.textKeyDown()); }, false);
            var okBtn = element[0].children[1].children[0].children[0].children[2].children[1];
            okBtn.addEventListener('click', function(){ scope.$apply(scope.btnRefOKClick()); }, false);

            scope.BodyClick = function(){
                if(scope.IsFocuse) {
                    var eventNode = event.srcElement;

                    while(eventNode){
                        if(eventNode == document ||eventNode == undefined || eventNode.tagName == undefined ||
                            eventNode.tagName.toLowerCase() == 'html' || eventNode.tagName.toLowerCase() == 'body'){

                            if(!scope._IsTouchFind){
                                scope.IsFocuse = false;
                                document.removeEventListener('click', scope.BodyClick, true);
                                scope.blur();
                            }
                            else{
                                scope._IsTouchFind = false;
                            }
                            
                            break;
                        }
                        else if(eventNode == element[0]) {
                            break;
                        }
                        eventNode = eventNode.parentNode;
                    }
                }
            };

            for(var i=0; i<scope._DataGridElement.children.length; i++){
                var column = {
                    Type: BaseEnum.ControlType.TextBox,
                    IsFilter: true,
                    DisplayName: 'XXX',
                    Width: '100px',
                    ValueField: '_id',
                    Round: null,         //数值和百分比控件可以使用
                    Enum: null,
                    CalendarType: BaseEnum.DateTimeFormat.DateTime    //日历控件可以使用
                };

                var columnDom = scope._DataGridElement.children[i];
                if (columnDom.getAttribute("type") != undefined && columnDom.getAttribute("type").trim() != "") {
                    var type = columnDom.getAttribute("type").trim().toLowerCase();

                    if(type == 'textbox' || type == '0'){
                        column.Type = BaseEnum.ControlType.TextBox;
                    }
                    else if(type == 'checkbox' || type == '1'){
                        column.Type = BaseEnum.ControlType.CheckBox;
                    }
                    else if(type == 'numberbox' || type == '2'){
                        column.Type = BaseEnum.ControlType.NumberBox;
                    }
                    else if(type == 'percentbox' || type == '3'){
                        column.Type = BaseEnum.ControlType.PercentBox;
                    }
                    else if(type == 'dropdownlist' || type == '4'){
                        column.Type = BaseEnum.ControlType.DropDownList;
                        column.Enum = columnDom.getAttribute("enum").trim();
                    }
                    else if(type == 'calendar' || type == '6'){
                        column.Type = BaseEnum.ControlType.Calendar;
                    }
                }
                if (columnDom.getAttribute("displayname") != undefined && columnDom.getAttribute("displayname").trim() != "") {
                    column.DisplayName = columnDom.getAttribute("displayname").trim();
                }
                if (columnDom.getAttribute("width") != undefined && columnDom.getAttribute("width").trim() != "") {
                    column.Width = columnDom.getAttribute("width").trim();
                }
                if (columnDom.getAttribute("valuefield") != undefined && columnDom.getAttribute("valuefield").trim() != "") {
                    column.ValueField = columnDom.getAttribute("valuefield").trim();
                }
                if (columnDom.getAttribute("isfilter") != undefined && columnDom.getAttribute("isfilter").toLocaleLowerCase() == "false") {
                    column.IsFilter = false;
                }
                if (columnDom.getAttribute("round") != undefined && columnDom.getAttribute("round").trim() != "") {
                    var round = eval("(" + columnDom.getAttribute("round").trim() + ")");

                    var precision = 2;
                    var roundType = BaseEnum.RoundType.AccondValueRound;
                    var roundValue = 5;

                    if(round.Precision != undefined){
                        precision = round.Precision;
                    }
                    if(round.RoundType != undefined){
                        roundType = round.RoundType;
                    }
                    if(round.RoundValue != undefined){
                        roundValue = round.RoundValue;
                    }

                    column.Round = new BaseClass.Round(precision, roundType, roundValue);
                }
                if (columnDom.getAttribute("calendartype") != undefined && columnDom.getAttribute("calendartype").trim() == "date") {
                    column.CalendarType = BaseEnum.DateTimeFormat.Date;
                }                
                scope.Columns.push(column);
            }

            scope.Module = BaseModule.initModule(scope, scope.EntityName);
            scope.Module.PageSize = 13;
            if(scope.Condition != undefined){
                scope.Module.Condition = scope.Condition;
            }
            if(scope.OrderBy != undefined){
                scope.Module.OrderBy = scope.OrderBy;
            }
            if(scope.Populate != undefined){
                scope.Module.Populate = scope.Populate;
            }
            scope.Module.LoadMode = BaseEnum.LoadMode.CacheAndPaging;

            scope.$watch(
                function(){
                    return attrs["enabled"];
                },
                function(){
                    if (attrs["enabled"] != undefined && attrs["enabled"].trim().toLocaleLowerCase() == "false") {
                        scope.Enabled = false;
                    }
                    else{
                        scope.Enabled = true;
                    }
                }
            );

            scope.$watch(
                function(){
                    return attrs["visible"]
                },
                function(){
                    if (attrs["visible"] != undefined && attrs["visible"].trim().toLocaleLowerCase() == "false") {
                        scope.Visible = false;
                    }
                    else{
                        scope.Visible = true;
                    }
                }
            );
        }
    }
}]);